#include <numeric>
#include <limits>
#include <set>
#include <string>
#include <vector>
#include <algorithm>
#include <cmath>
#include <thread>
#include <functional>
#include <unistd.h>
#include <chrono>
#include <memory>
#include <atomic>
#include <thread>
#include <mutex>
#include <queue>

using namespace std;

#include <iostream>
#include <vector>
#include <queue>
#include <functional>
#include <map>

#include <iostream>
#include <memory>

#include <iostream>
#include <vector>
#include <algorithm>
#include <bitset>


#include <iostream>
#include <string>
#include <cctype> // for isxdigit
#include <stdio.h>
#include <sqlite3.h>

#include <google/protobuf/arena.h>
#include "message.pb.h"

#include <stdlib.h>
#include <iostream>

static int callback(void* NotUsed, int argc, char** argv, char** azColName) {
    for (int i = 0; i < argc; i++) {
      printf("%s = %s,", azColName[i], argv[i] ? argv[i] : "NULL");
    }
    printf("\n");
    return 0;
}

// int sqlite3_exec(
//     sqlite3* db,                   // 数据库连接对象
//     const char* sql,               // 要执行的 SQL 语句或脚本
//     sqlite_callback callback,       // 回调函数（可选）
//     void* userdata,                // 用户数据（可选，传递给回调函数）
//     char** errmsg                  // 错误信息（可选）
// );


// -DSQLITE_ENABLE_ANY_LOCK
// int sqlite_page_zip(sqlite3 *db){
//   // 启用压缩和设置页面大小
//   int rc = sqlite3_exec(db, "PRAGMA page_size = 4096;", 0, 0, &err_msg);
//   if (rc!= SQLITE_OK) {
//       fprintf(stderr, "设置页面大小失败: %s\n", err_msg);
//       sqlite3_free(err_msg);
//       sqlite3_close(db);
//       return 1;
//   }
//   rc = sqlite3_exec(db, "PRAGMA compression = ON;", 0, 0, &err_msg);
//   if (rc!= SQLITE_OK) {
//       fprintf(stderr, "启用压缩失败: %s\n", err_msg);
//       sqlite3_free(err_msg);
//       sqlite3_close(db);
//       return 1;
//   }
// }

//二进制的数据写入到文件中；
// int main() {
    // sqlite3 *db;
    // char* errmsg = 0;

    // //执行 SQL 打开；
    // int rc = sqlite3_open("../test.db", &db);
    // if (rc!= SQLITE_OK) {
    //     fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
    //     sqlite3_close(db);
    //     return 1;
    // }
    // else {
    //     fprintf(stdout, "Opened database successfully\n");
    // }
    // //执行 SQL 插入语句；
    // const char* sql1 = "CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, age INTEGER NOT NULL);"
    //                   "INSERT INTO users (name, age) VALUES ('Alice', 30);"
    //                   "INSERT INTO users (name, age) VALUES ('Bob', 25);";

    // rc = sqlite3_exec(db, sql1, callback, 0, &errmsg);

    // if (rc != SQLITE_OK) {
    //     fprintf(stderr, "SQL error: %s", errmsg);
    //     sqlite3_free(errmsg);
    // } else {
    //     fprintf(stdout, "Records created successfully\n");
    // }

    // //执行 SQL 更细操作；
    // // sql = "UPDATE users SET age = 26 WHERE name = 'Alice'";
    // // rc = sqlite3_exec(db, sql, 0, 0, &errmsg);


    // // 执行 SQL 查询；
    // const char *sql2 = "SELECT * FROM users;";
    // rc = sqlite3_exec(db, sql2, callback, 0, &errmsg);

    // if (rc != SQLITE_OK) {
    //     fprintf(stderr, "SQL error: %s\n", errmsg);
    //     sqlite3_free(errmsg);
    // }

    // // 执行 SQL 关闭；
    // sqlite3_close(db);

    // StackMessage message;
    // message.set_pid(111);
    // message.set_tid(222);
    // auto stack_info = message.mutable_stack_info();
    // stack_info->Add("stack1");
    // stack_info->Add("stack2");
    // stack_info->Add("stack3");

    // int size = message.ByteSizeLong();
    // void* buffer = malloc(size);
    // message.SerializeToArray(buffer, size);
    // printf("size:%d\n",size);

    // // 可以将序列化后的数据存储到文件或通过网络发送等
    // FILE* file = fopen("../stack_message.bin", "wb");
    // fwrite(buffer, 1, size, file);
    // fclose(file);

    // free(buffer);
//     return 0;
// }


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <zlib.h>

FILE *file = NULL;
const int compressedLen = 1024;
Bytef* compressedData = NULL;

int init(){
  compressedData = (Bytef*)malloc(compressedLen*sizeof(Bytef));
  if (compressedData == NULL) {
    fprintf(stderr, "malloc error\n");
    return 1;
  }

  // 可以将序列化后的数据存储到文件或通过网络发送等
  file = fopen("../zlib_file.zlib", "wb");

  if (file == NULL) {
    fprintf(stderr, "open file error\n");
    return 1;
  }
  return 0;
}

int compress_str(const char* input, FILE* file){

  uLong inputLen = strlen(input) + 1; // +1 to include the null terminator
  uLongf compressedLen = compressBound(inputLen);
  memset(compressedData, 0, sizeof(compressedData));

  

  int ret = compress2(compressedData, &compressedLen, (const Bytef *)input, inputLen, Z_BEST_COMPRESSION);
  if (ret!= Z_OK) {
      fprintf(stderr, "Compression failed with error code %d.\n", ret);
      return 1;
  }

  fwrite(&compressedLen, sizeof(uLongf), 1, file);
  fwrite(compressedData, 1, compressedLen, file);

  return 0;
}

// 压缩；
int main() {
  // if (init() != 0 ) {
  //   return 1;
  // }

  // const char *input1 = "test;[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];fflush 1\n";
  // const char *input2 = "tset;[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];[unknown];fflush 2\n";
    
  // if (compress_str(input1, file) == 1) {
  //   fprintf(stderr, "compress_str error\n");
  // }
  //  printf("111\n");
  // if (compress_str(input2, file) == 1) {
  //   fprintf(stderr, "compress_str error\n");
  // }
  // fclose(file);

  // 可以将序列化后的数据存储到文件或通过网络发送等
  FILE* rfile = fopen("../zlib_file.zlib", "rb");
  if (rfile == NULL) {
    fprintf(stderr, "Failed to open the compressed file.\n");
    return 1;
  }
  uLongf compressedLen = 0;

  while (!feof(rfile)) {
    if (fread(&compressedLen, sizeof(uLongf), 1, rfile)!= 1) {
      if (feof(rfile)) {
        break;  // 文件结束，正常退出循环
      } else {
        fprintf(stderr, "Error reading compressed data length.\n");
        fclose(rfile);
        return 1;
      }
    }
    // 分配内存用于存储压缩数据
    Bytef *compressedData = (Bytef *)malloc(compressedLen);
    if (compressedData == NULL) {
        fprintf(stderr, "Memory allocation failed for compressed data.\n");
        fclose(rfile);
        return 1;
    }
    // 读取当前数据块的压缩数据
    if (fread(compressedData, 1, compressedLen, rfile)!= compressedLen) {
        fprintf(stderr, "Error reading compressed data.\n");
        free(compressedData);
        fclose(rfile);
        return 1;
    }

    // 分配内存用于存储解压缩后的数据，初始假设一个较大空间，实际可按需调整
    uLongf uncompressedLen = 2048;
    Bytef *uncompressedData = (Bytef *)malloc(uncompressedLen);
    if (uncompressedData == NULL) {
        fprintf(stderr, "Memory allocation failed for uncompressed data.\n");
        free(compressedData);
        fclose(rfile);
        return 1;
    }

    // 解压缩数据
    int ret = uncompress(uncompressedData, &uncompressedLen, compressedData, compressedLen);
    if (ret!= Z_OK) {
        fprintf(stderr, "Uncompression failed with error code %d.\n", ret);
        free(compressedData);
        free(uncompressedData);
        fclose(rfile);
        return 1;
    }

    // 输出解压缩后的数据（这里可根据实际需求进行更合适的处理，比如存储到其他地方等）
    printf("Uncompressed data: %s\n", uncompressedData);
    // 释放内存
    free(compressedData);
    free(uncompressedData);
  }
  return 0;
}
